import { Injectable } from '@angular/core';
import { GanttModel, EditModel, PredecessorLinkModel } from './gantt.model';
import * as moment from 'moment';
import { GanttService } from './gantt.service';
import { PREVTYPE } from './gantt.config';

@Injectable({
  providedIn: 'root'
})
export class GanttHelperService {
  public settingVisible = false;
  public currentTask: GanttModel;
  // relations: any = [];

  public editInfo: EditModel;

  public constructor(private ganttService: GanttService) {

  }



  public showRelation(task) {
    this.currentTask = task;
    let showRelation = [];
    if (task.prevRelation.length > 0) {
      task.prevRelation.forEach((item) => {
        let relation = this.translateNumber(item.relation);
        let delay = item.delay ? `+${item.delay}` : '';
        if (item.prevId && !item.isDelete) {
          let string = `${item.prevId}${relation}${delay}`;
          showRelation.push(string);
        }
      });
    }
    if (showRelation.length == 0) {
      return '请选择';
    }
    return showRelation.join(',');
  }

  public translateNumber(relation) {
    if (relation == PREVTYPE.FS) {
      return 'FS';
    }
    if (relation == PREVTYPE.SS) {
      return 'SS';
    }
    if (relation == PREVTYPE.FF) {
      return 'FF';
    }
    if (relation == PREVTYPE.SF) {
      return 'SF';
    }
  }

  public showSettings(task: GanttModel) {
    let relations = [];
    task.prevRelation.forEach((ele) => {
      relations.push(ele);
    });
    if (relations.length === 0) {
      relations.push(new PredecessorLinkModel({
        relation: 1,
        delay: 0
      }));
    }

    console.log(relations);
    let showDuration = task.showDuration;
    this.editInfo = new EditModel({
      relations,
      taskName: task.taskName,
      showDuration
    });
    this.settingVisible = true;
  }

  public settingSave() {
    let relations = this.editInfo.relations;
    let prevRelation = [];
    let currentTask = this.currentTask;
    relations.forEach((element) => {
      if (element.prevId && element.relation) {
        prevRelation.push(new PredecessorLinkModel({
          id: element.id,
          prevId: parseInt(element.prevId),
          relation: element.relation,
          delay: element.delay,
          isDelete: element.isDelete
        }));
      }
    });
    let checkResult = this.checkRelations(prevRelation);
    if (checkResult) {
      // this.createNotification('error', '请检查', checkResult)
      alert(checkResult);
    } else {
      currentTask.prevRelation = prevRelation;
      currentTask.taskName = this.editInfo.taskName;
      // currentTask.showDuration = this.editInfo.showDuration;
      this.getShowDuration(currentTask, this.editInfo.showDuration);
      this.ganttService.updateAllTaskInfo();
      // this.ganttService.dealWithExceptDate();
      this.settingVisible = false;
    }
  }

  public checkRelations(relations: any[]) {
    // let relations = this.relations;
    let currentTask = this.currentTask;
    let checkRepeat: string;
    let checkSameId: string;
    let checkLoop: string;
    let checkPrevId: string;
    let allTasks = this.ganttService.allTasks;
    let taskLength = allTasks.length;
    let usefulRelation = [];
    relations.forEach((rela) => {
      if (!rela.isDelete) {
        usefulRelation.push(rela);
      }
    });
    // 检查4: 非法字符
    usefulRelation.forEach((element) => {
      let id = parseInt(element.prevId);
      if (isNaN(id)) {
        checkPrevId = `任务标识必须为数字`;
        return false;
      } else {
        if (id < 1 || id > taskLength) {
          checkPrevId = `任务标识不存在, error:'${id}'`;
          return false;
        }
      }
    });

    // 检查1： 前置任务id重复
    usefulRelation.forEach((i) => {
      let id = i.prevId;
      let idArray = [];
      usefulRelation.forEach((j) => {
        if (j.prevId === id) {
          idArray.push(j);
        }
      });
      if (idArray.length > 1) {
        checkRepeat = `任务'${idArray[0]}'两次链接到同一个后续任务`;
        return;
      }
    });

    // 检查2：prevId与任务Id相同
    usefulRelation.forEach((element) => {
      let id = element.prevId;
      if (id == currentTask.id) {
        checkSameId = `前置任务不能为自己, error:${id}`;
        return;
      }
    });


    // 检查3: 是否产生循环
    usefulRelation.forEach((element) => {
      let id = element.prevId;
      let prevTask = allTasks[id - 1];
      let check;
      if (prevTask && prevTask.prevRelation.length > 0) {
        check = prevTask.prevRelation.findIndex((relation) => {
          return relation.prevId == currentTask.id;
        });
        if (check !== -1) {
          checkLoop = `任务'${id}'产生循环`;
          return;
        }
      }
    });

    if (checkPrevId) {
      return checkPrevId;
    } else if (checkRepeat) {
      return checkRepeat;
    } else if (checkSameId) {
      return checkSameId;
    } else if (checkLoop) {
      return checkLoop;
    } else {
      return false;
    }
  }

  public settingCancel() {
    this.settingVisible = false;
  }

  public getShowDuration(task, value) {
    let wantedShow = value;
    let exceptDate = this.ganttService.exceptDate;
    let startDate = task.startDate;
    let endDate;
    if (startDate) {
      // 先判断有没有受例外日期的影响
      let startUnix1 = moment(startDate).unix();
      let endUnix1 = moment(startDate).add(wantedShow - 1, 'days').unix();
      // 先根据例外日期，改变任务的开始时间和结束时间
      exceptDate.forEach((item) => {
        // 任务结束时间在例外日期之间
        if (endUnix1 <= item.endDate && endUnix1 >= item.startDate) {
          let correctDate = moment.unix(item.endDate).clone().add(1, 'days');
          endDate = correctDate;
        }
      });

      // 再统计任务中所有的例外日期总天数
      let startUnix2 = moment(startDate).unix();
      let endUnix2;
      if (endDate) {
        endUnix2 = moment(endDate).unix();
      } else {
        endDate = moment(startDate).add(wantedShow - 1, 'days');
        endUnix2 = endUnix1;
      }
      let allExcept = 0;
      exceptDate.forEach((item) => {
        // 例外日期在任务的开始时间和结束时间之间
        if (startUnix2 <= item.startDate && endUnix2 >= item.endDate) {
          let exceptDuration = moment.unix(item.endDate).clone().diff(moment.unix(item.startDate), 'days') + 1;
          allExcept = allExcept + exceptDuration;
        }
      });

      let duration = moment(endDate).clone().diff(moment(startDate), 'days') + 1;
      let showCount = duration - allExcept;

      if (showCount !== wantedShow) {
        let changes = wantedShow - showCount;
        task.duration = duration + changes;
      } else {
        task.duration = duration;
      }
    } else {
      task.duration = value;
      task.showDuration = value;
    }
  }

  public deleteRelation(index: number) {
    // this.editInfo.relations.splice(index, 1);
    this.editInfo.relations[index].isDelete = 1;
  }

  public addRelation() {
    this.editInfo.relations.push(new PredecessorLinkModel({
      relation: 1,
      delay: 0
    }));
  }



}
